package com.itheima.sys.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.itheima.common.constants.RocketMQConstants;
import com.itheima.common.entity.NotifyMessage;
import com.itheima.common.entity.NotifyMessageConstant;
import com.itheima.common.exception.NcException;
import com.itheima.common.exception.enums.ResponseEnum;
import com.itheima.common.threadlocal.UserHolder;
import com.itheima.common.util.BeanHelper;
import com.itheima.common.util.DateTimeUtil;
import com.itheima.common.util.StringUtil;
import com.itheima.sys.dto.CompanyDTO;
import com.itheima.sys.dto.CompanyUserDTO;
import com.itheima.sys.dto.UserJoinCompanyDTO;
import com.itheima.sys.entity.Company;
import com.itheima.sys.entity.CompanyUser;
import com.itheima.sys.entity.SysUser;
import com.itheima.sys.mapper.CompanyMapper;
import com.itheima.sys.properties.OssProperties;
import com.itheima.sys.service.ICompanyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sys.service.ICompanyUserService;
import com.itheima.sys.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static com.itheima.common.constants.RocketMQConstants.TAGS.USER_APPLY_TAGS;
import static com.itheima.common.constants.RocketMQConstants.TOPIC.USER_TOPIC_NAME;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2020-12-13
 */
@Slf4j
@Service
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> implements ICompanyService {

    @Autowired
    private ICompanyUserService companyUserService;

    @Override
    public List<CompanyDTO> queryUserJoinCompany(Long userId) {
        List<Company> companyList = this.getBaseMapper().queryUserJoinCompany(userId);
        if (!companyList.isEmpty()) {
            return BeanHelper.copyWithCollection(companyList, CompanyDTO.class);
        }
        return null;
    }

    @Override
    public CompanyDTO queryCurrentCompany() {
        Long companyId = UserHolder.getCompanyId();
        Company company = this.getById(companyId);
        if (company == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        return BeanHelper.copyProperties(company, CompanyDTO.class);
    }

    @Override
    @Transactional
    public void updateCompany(CompanyDTO companyDTO) {
        Long companyId = UserHolder.getCompanyId();
        Company company = BeanHelper.copyProperties(companyDTO, Company.class);
        company.setId(companyId);
        boolean b = this.updateById(company);
        if (!b) {
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }
        //修改员工表中 企业信息
        UpdateWrapper<CompanyUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(CompanyUser::getCompanyId, companyId);
        updateWrapper.lambda().set(CompanyUser::getCompanyName, companyDTO.getName());
        boolean b1 = companyUserService.update(updateWrapper);
        if (!b1) {
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }
    }

    //允许上传的图片类型
    private static final List<String> allowedType = Arrays.asList("image/jpeg", "image/bmp", "image/png");

    @Autowired
    private OSS ossClient;

    @Autowired
    private OssProperties prop;

    @Override
    public String uploadImage(MultipartFile file) {
        //1.判断文件MIME类型是否为图片
        String contentType = file.getContentType();
        if (!allowedType.contains(contentType)) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        //2.判断文件内容是否为图片  ImageIO该方法适用的图片格式为 bmp/gif/jpg/png
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage == null) {
                throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //上传文件
        try (InputStream ins = file.getInputStream();) {
            String timestr = DateTime.now().toString(DateTimeUtil.TIME_FORMAT_6);
            String randomFileName = timestr + "-" + file.getOriginalFilename();
            // 上传文件流
            PutObjectResult putObjectResult = ossClient.putObject(prop.getBucket(), randomFileName, ins);
            log.info("上传文件：{}", randomFileName + "，结果：" + putObjectResult.getResponse());
            return prop.getHost() + "/" + randomFileName;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<CompanyDTO> queryCompany(String keyword, String industryId) {
        QueryWrapper<Company> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(keyword)) {
            queryWrapper.lambda().like(Company::getName, keyword);
        }
        if (StringUtils.isNotBlank(industryId)) {
            queryWrapper.lambda().eq(Company::getIndustryId, industryId);
        }
        List<Company> companyList = this.list(queryWrapper);
        if (!CollectionUtils.isEmpty(companyList)) {
            return BeanHelper.copyWithCollection(companyList, CompanyDTO.class);
        }
        return null;
    }

    @Autowired
    private ISysUserService sysUserService;


    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void applyJoinCompany(UserJoinCompanyDTO userJoinCompanyDTO) {
        Long companyId = userJoinCompanyDTO.getCompanyId();
        //1.判断系统用户ID是否存在,更新部分用户表信息 姓名
        Long userId = userJoinCompanyDTO.getUserId();
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        sysUser.setUsername(userJoinCompanyDTO.getUsername());
        boolean b = sysUserService.updateById(sysUser);
        if(!b){
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }
        Company company = this.getById(userJoinCompanyDTO.getCompanyId());
        //2.向企业员工表中新增记录 (状态为不可用)- 新增前判断员工记录是否存在
        QueryWrapper<CompanyUser> companyUserQueryWrapper = new QueryWrapper<>();
        companyUserQueryWrapper.lambda().eq(CompanyUser::getCompanyId, companyId);
        companyUserQueryWrapper.lambda().eq(CompanyUser::getUserId, userId);
        int count = companyUserService.count(companyUserQueryWrapper);
        CompanyUser companyUser = null;
        if(count==0){
            companyUser = BeanHelper.copyProperties(userJoinCompanyDTO, CompanyUser.class);
            companyUser.setEnable(false);
            companyUser.setCompanyName(company.getName());
            companyUser.setImageUrl(userJoinCompanyDTO.getImageUrl());
            companyUser.setMobile(sysUser.getMobile());
            boolean b1 = companyUserService.save(companyUser);
            if(!b1){
                throw new NcException(ResponseEnum.INSERT_OPERATION_FAIL);
            }
        }else{
            companyUser = companyUserService.getOne(companyUserQueryWrapper);
        }
        //3.创建推送消息对象
        NotifyMessage notifyMessage = new NotifyMessage();
        notifyMessage.setApplyUserId(companyUser.getId());
        notifyMessage.setCompanyId(companyId);
        notifyMessage.setMessageType(NotifyMessageConstant.COMPANY_APPLY);
        notifyMessage.setTitle("有新员工申请加入企业");
        notifyMessage.setContent(userJoinCompanyDTO.getUsername()+ " 申请加入 "+company.getName()+",请及时审批！");
        notifyMessage.setCreateTime(new Date());

        //设置接收方(当前企业管理员)--对之前查询企业管理员方法进行修改 增加companyId
        CompanyUserDTO currentAdmin = companyUserService.getCurrentAdmin(companyId);
        if(currentAdmin!=null){
            notifyMessage.setTargets(Arrays.asList(currentAdmin.getMobile()));
            notifyMessage.setApproveUserId(currentAdmin.getId());
        }else{
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }

        //4.将推送消息对象 发送到 RocketMQ中
        rocketMQTemplate.convertAndSend(USER_TOPIC_NAME+":"+ USER_APPLY_TAGS, notifyMessage);
    }

    /**
     * 审核申请加入企业操作
     * @param companyUserId 企业员工ID
     * @param approved 审核结果
     * @param remark 审核备注
     */
    @Override
    @Transactional
    public void allowedJonCompany(Long companyUserId, Boolean approved, String remark) {
        Long companyId = UserHolder.getCompanyId();
        //1.更新员工表状态
        CompanyUser companyUser = companyUserService.getById(companyUserId);
        if(companyUser==null){
            throw new NcException(ResponseEnum.COMPANY_USER_NOT_FOUND);
        }
        NotifyMessage notifyMessage = new NotifyMessage();
        //推送目标 申请用户 手机号
        notifyMessage.setTargets(Arrays.asList(companyUser.getMobile()));
        notifyMessage.setMessageType(NotifyMessageConstant.COMPANY_APPLY);
        notifyMessage.setCreateTime(new Date());
        notifyMessage.setTitle("申请加入企业结果");
        remark = StringUtils.isNotBlank(remark) ? "  管理员备注："+remark : "";
        if(approved){
            //2.1同意加入企业
            companyUser.setEnable(approved);
            boolean b = companyUserService.updateById(companyUser);
            if(!b){
                throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
            }
            //2.1向申请者发送推送通知
             notifyMessage.setContent("申请通过"+remark);
            //2.2 修改系统用户表 上次登录企业ID
            Long userId = companyUser.getUserId();
            SysUser sysUser = sysUserService.getById(userId);
            if(sysUser!=null){
                sysUser.setLastLoginCompanyId(companyId);
                boolean b1 = sysUserService.updateById(sysUser);
                if(!b1){
                    throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
                }
            }
            //TODO 审核通过后 给普通用户赋予普通用户角色 ROLE_USER_EMPLOYEE
            //3.将推送消息对象 发送到 RocketMQ中
            rocketMQTemplate.convertAndSend(USER_TOPIC_NAME+":"+ USER_APPLY_TAGS, notifyMessage);
            return;
        }
        //2.3 不同意
        //2.向申请者发送推送通知
        notifyMessage.setContent("申请拒绝"+remark);

        //3.将推送消息对象 发送到 RocketMQ中
        rocketMQTemplate.convertAndSend(USER_TOPIC_NAME+":"+ USER_APPLY_TAGS, notifyMessage);
    }
}
